package com.fzkj.nio.part2;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;

/**
 * nio非阻塞通信下入门案例：服务端
 */
public class Server {

    public static void main(String[] args) {
        System.out.println("启动服务端");
        try {
            // 1、获取通道
            ServerSocketChannel ssChannel = ServerSocketChannel.open();
            // 2、切换为非阻塞模式
            ssChannel.configureBlocking(false);
            // 3、绑定连接端口
            ssChannel.bind(new InetSocketAddress(2323));
            // 4、获取选择器
            Selector selector = Selector.open();
            // 5、将通道注册到选择器中，开始监听接收事件
            ssChannel.register(selector, SelectionKey.OP_ACCEPT);
            // 6、使用selector选择器轮询已经就绪的事件
            while(selector.select() > 0){ // 拿选择器中的事件
                // 7、获取选择器中的所有注册的通道中已经就绪的事件
                Iterator<SelectionKey> iterators = selector.selectedKeys().iterator();
                // 8、开始遍历准备好的事件
                while(iterators.hasNext()){
                    // 提取当前事件
                    SelectionKey sk = iterators.next();
                    // 判断当前事件具体是什么
                    if (sk.isAcceptable()){ // 连接事件
                        // 直接获取当前接入的客户端通道
                        SocketChannel sc = ssChannel.accept();
                        // 切换成非阻塞模式
                        sc.configureBlocking(false);
                        // 将本客户端通道注册到选择器，进行读监听
                        sc.register(selector, SelectionKey.OP_READ);

                    } else if(sk.isReadable()){ // 读事件
                        // 获取当前选择器上的读就绪事件
                        SocketChannel sChannel = (SocketChannel) sk.channel();
                        // 读取数据
                        ByteBuffer buffer = ByteBuffer.allocate(1024);
                        int len;
                        while((len = sChannel.read(buffer)) > 0){
                            buffer.flip();
                            System.out.println(new String (buffer.array(), 0, len));
                            buffer.clear();
                        }
                    }
                    // 处理完毕之后移除当前事件
                    iterators.remove();

                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
